From 6e5243b3287362b32d491ad75e674e38a3825c19 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 6 Apr 2006 18:39:00 +0100 Subject: [PATCH] Do not create blkback vbd kernel thread until fully connected to frontend driver. Otherwise the kernel thread may crash trying to access the non-existent shared ring. Signed-off-by: Keir Fraser --- .../drivers/xen/blkback/blkback.c | 2 +- .../drivers/xen/blkback/common.h | 1 - .../drivers/xen/blkback/xenbus.c | 38 +++++++++++-------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c index 4faf117069..fe2367a8fc 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -287,7 +287,7 @@ static int end_block_io_op(struct bio *bio, unsigned int done, int error) * NOTIFICATION FROM GUEST OS. */ -void blkif_notify_work(blkif_t *blkif) +static void blkif_notify_work(blkif_t *blkif) { blkif->waiting_reqs = 1; wake_up(&blkif->wq); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h index 58939d6ab2..a32466e3a7 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h @@ -129,7 +129,6 @@ void blkif_interface_init(void); void blkif_xenbus_init(void); -void blkif_notify_work(blkif_t *blkif); irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs); int blkif_schedule(void *arg); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c index d0ec094d66..011bec8d19 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -46,10 +46,29 @@ static void backend_changed(struct xenbus_watch *, const char **, static void update_blkif_status(blkif_t *blkif) { - if (blkif->irq && blkif->vbd.bdev && - (blkif->be->dev->state != XenbusStateConnected)) { - connect(blkif->be); - blkif_notify_work(blkif); + int err; + + /* Not ready to connect? */ + if (!blkif->irq || !blkif->vbd.bdev) + return; + + /* Already connected? */ + if (blkif->be->dev->state == XenbusStateConnected) + return; + + /* Attempt to connect: exit if we fail to. */ + connect(blkif->be); + if (blkif->be->dev->state != XenbusStateConnected) + return; + + blkif->xenblkd = kthread_run(blkif_schedule, blkif, + "xvd %d %02x:%02x", + blkif->domid, + blkif->be->major, blkif->be->minor); + if (IS_ERR(blkif->xenblkd)) { + err = PTR_ERR(blkif->xenblkd); + blkif->xenblkd = NULL; + xenbus_dev_error(blkif->be->dev, err, "start xenblkd"); } } @@ -215,17 +234,6 @@ static void backend_changed(struct xenbus_watch *watch, return; } - be->blkif->xenblkd = kthread_run(blkif_schedule, be->blkif, - "xvd %d %02x:%02x", - be->blkif->domid, - be->major, be->minor); - if (IS_ERR(be->blkif->xenblkd)) { - err = PTR_ERR(be->blkif->xenblkd); - be->blkif->xenblkd = NULL; - xenbus_dev_error(dev, err, "start xenblkd"); - return; - } - device_create_file(&dev->dev, &dev_attr_physical_device); device_create_file(&dev->dev, &dev_attr_mode); -- 2.30.2